#include "comm.h"
#include <string.h>

static uint8_t
BIT8_XOR_Check_Sum(const uint8_t* buf, uint32_t len) {
    uint32_t i;
    uint8_t checksum = 0;

    for (i = 0; i < len; ++i) {
        checksum ^= *(buf++);
    }
    return checksum;
}

static void
HexToString(uint8_t* pHex, uint8_t* pAscii, uint32_t nLen) {
    unsigned char Nibble[2];
    unsigned int i, j;
    for (i = 0; i < nLen; i++) {
        Nibble[0] = (pHex[i] & 0xF0) >> 4;
        Nibble[1] = pHex[i] & 0x0F;
        for (j = 0; j < 2; j++) {
            if (Nibble[j] < 10) {
                Nibble[j] += 0x30;
            } else {
                if (Nibble[j] < 16) {
                    Nibble[j] = Nibble[j] - 10 + 'A';
                }
            }
            *pAscii++ = Nibble[j];
        }
    }
    *pAscii++ = 0x0A;
    *pAscii++ = 0x0D;
}
static void
StringToHex(uint8_t* src, uint32_t srclen, uint8_t* pAscii, uint32_t nLen) {
    uint16_t i;
    uint8_t high = 0, low = 0;
    if ((srclen != 2) || (srclen % 2 != 0) || ((srclen / 2) != nLen) || src == NULL || pAscii == NULL ) {
        return;
    }

    for (i = 0; i < srclen; i++) {
        high = ((*src > '9') && ((*src <= 'F') || (*src <= 'f'))) ? *src - 48 - 7 : *src - 48;
        low = (*(++src) > '9' && ((*src <= 'F') || (*src <= 'f'))) ? *(src) - 48 - 7 : *(src) - 48;
        pAscii[i] = ((high & 0x0f) << 4 | (low & 0x0f));
    }
}


//性能好一点比memstr
char*
memfind(const char* buf, int buf_size, const char* subinfo, int info_size) {
    int i;
    char* p;
    if (buf == NULL || buf_size <= 0 || subinfo == NULL || info_size <= 0) {
        return NULL;
    }
    p = (char*)buf;
    for (i = 0; i < buf_size - info_size; i++) {
        if (*p == *subinfo) {
            if (memcmp(p, subinfo, info_size) == 0) {
                return p;
            }
        }
        p++;
    }
    return NULL;
}
//简单一点的
static char*
my_memstr(const char* str1, uint32_t len1, const char* str2) {
    char* p1;
    int i, len2, j;

    if (str1 == NULL || str2 == NULL) {
        return NULL;
    }

    p1 = (char*)str2;

    len2 = 0;
    while (*p1++ != 0) {
        len2++;    //计算字符串 *str2 中一共有多少个字符
    }
    if (len2 > len1) {
        return NULL;    //待查找的字符串 *str2 的字符数量比缓冲区中字符数量还多，认为不合法
    }

    for (i = 0; i <= len1 - len2; i++) { //str1中若存在str2，查找len1-len2次一定能找到，若找不到，则说明不存在
        p1 = (char*)&str1[i];
        j = 0;
        while (str1[j + i] == str2[j]) {
            j++;
            if (j >= len2) {
                return p1;    // bd db 找到了，返回 bd 的地址
            }
        }
    }

    return NULL;    //没有找到，返回NULL
}

uint8_t
BIT8_CRC_Check(uint8_t* info, uint16_t len) {
    uint8_t* Scrc, scrc, crc;
    Scrc = (uint8_t*)strstr((const char*)info, "*");
    if (Scrc) {
        crc = Comm_Handle.BIT8_XOR_Check_Sum(info + 1, (Scrc - info) -1);
        Comm_Handle.StringToHex(Scrc + 1, 2, &scrc, 1);
        if (crc == scrc) {
            return 1;
        }
    }
    return 0;
}
Comm_Handle_t Comm_Handle = {
    .BIT8_XOR_Check_Sum = BIT8_XOR_Check_Sum,
    .HexToString = HexToString,
    .StringToHex = StringToHex,
    .MemFind = memfind,
    .BIT8_CRC_Check = BIT8_CRC_Check,
    .my_memstr = my_memstr,
};


